package com.dap.dao.interceptor;

/**
 * @author wangmin
 * @discription
 * @created 2019-10-21 10:34
 */
public abstract class SqlStringUtils {
    /**
     * 判断 text 的 endIndex 之后的文本是否在引号之外
     * @param text 要判断的文本
     * @param endIndex 结束下标
     */
    public static boolean isOutsideQuotationMark(String text, int endIndex) {
        boolean currentInSingle = false;    // 当前在单引号之内
        boolean currentInDouble = false;    // 当前在双引号之内
        boolean currentInField = false;     // 当前在`之内

        for (int i=0; i<endIndex; ) {
            char ch = text.charAt(i);

            if (!currentInSingle && !currentInDouble && !currentInField) {
                if ('\'' == ch) {
                    currentInSingle = true;
                    ++i;
                } else if ('"' == ch) {
                    currentInDouble = true;
                    ++i;
                } else if ('`' == ch) {
                    currentInField = true;
                    ++i;
                } else if ('\\' == ch) {
                    i += 2;
                } else {
                    ++i;
                }
            } else if (currentInSingle) {
                if ('\'' == ch) {
                    currentInSingle = false;
                    ++i;
                } else if ('\\' == ch) {
                    i += 2;
                } else {
                    ++i;
                }
            } else if (currentInDouble) {
                if ('"' == ch) {
                    currentInDouble = false;
                    ++i;
                } else if ('\\' == ch) {
                    i += 2;
                } else {
                    ++i;
                }
            } else if (currentInField) {
                if ('`' == ch) {
                    currentInField = false;
                    ++i;
                } else if ('\\' == ch) {
                    i += 2;
                } else {
                    ++i;
                }
            }
        }

        return !currentInSingle && !currentInDouble && !currentInField;
    }

    /**
     * 判断 text 的 fromIndex 之后的文本查找文本searchText, searchText需要在引号之外
     * @param text 要判断的文本
     * @param fromIndex 检查的起始下标
     */
    public static int indexOfOutsideQuotationMarks(String text, String searchText, int fromIndex) {
        final int searchLastIndex = text.length() - searchText.length();
        while (fromIndex <= searchLastIndex) {
            final int index = text.indexOf(searchText, fromIndex);
            if (index < 0) {
                return index;
            }

            if (isOutsideQuotationMark(text, index)) {
                return index;
            }

            fromIndex = index + searchText.length();
        }

        return -1;
    }
    public static int indexOfOutsideQuotationMarks(String text, String searchText) {
        return indexOfOutsideQuotationMarks(text, searchText, 0);
    }

    /**
     * 判断 text 查找最后一个searchText, searchText需要在引号之外
     * @param text 要判断的文本
     * @param searchText 查找的文本
     */
    public static int lastIndexOfOutsideQuotationMarks(String text, String searchText) {
        while (text.length() >= searchText.length()) {
            final int index = text.lastIndexOf(searchText);
            if (index < 0) {
                return index;
            }

            if (isOutsideQuotationMark(text, index)) {
                return index;
            }

            text = text.substring(0, index+searchText.length()-1);
        }

        return - 1;
    }



    public static void main(String[] args) {
        String s;
        boolean isOutside;
        int index, lastIndex;

        s = "";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "'";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "''";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "'sfsdf'";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "'sfsdf\"''";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "'sfsdf\"''\"'\\'";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);

        s = "'\\'\\\"\\\\";
        isOutside = isOutsideQuotationMark(s, s.length());
        System.out.println("isOutside=" + isOutside + ", string=" + s);


        s = "";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);

        s = " GROUP BY ";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);

        s = "GROUP BY ";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);

        s = "' GROUP BY '";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);

        s = "\" GROUP BY \"";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);

        s = "' GROUP BY ', \" GROUP BY \",  GROUP BY ";
        index = indexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("index=" + index + ", string=" + s);


        s = "";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);

        s = " GROUP BY ";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);

        s = "GROUP BY ";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);

        s = "' GROUP BY '";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);

        s = "\" GROUP BY \"";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);

        s = " GROUP BY , \" GROUP BY \",  GROUP BY ";
        lastIndex = lastIndexOfOutsideQuotationMarks(s, " GROUP BY ");
        System.out.println("lastIndex=" + lastIndex + ", string=" + s);
    }
}
